home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-09-25 | 25.8 KB | 1,031 lines | [TEXT/CWIE] |
- /*
- File: MoreOpenAndSave.cp
-
- Contains: wraps Navigation Services in an API which looks like Standard File
-
- Written by: Pete Gontier
-
- Copyright: Copyright (c) 1997-1998 Apple Computer, Inc.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
-
- <7> 9/1/98 PCG Universal Headers 3.2
- <6> 8/26/98 PCG in MOASI_HandleEvent, adjust timing of increment of foundItem
- <5> 27/7/98 QQQ Fix unused variable warnings.
- <4> 7/24/98 PCG obviate MOASI_GetSomeCurrentProcessInformation and
- MOASI_PLstrcpy
- <3> 7/11/98 PCG add back old version history
- <2> 7/11/98 PCG initial checkin
- */
-
- // who when what
- // --- -------- ------------------------------------------------------
- // PCG 12/10/97 new today; MOASI_StandardGetFile
- // PCG 12/13/97 MOASI_StandardPutFile
- // PCG 01/19/98 MOASI_StandardOpenDialog
- // (for Translation Manager)
- // PCG 04/02/98 fork from original MOAS project
- // (lose the system extension)
- // PCG 04/02/98 MOASI_CustomGetFile
- // PCG 04/02/98 MOASI_CustomPutFile
- // PCG 04/07/98 eliminate calls to PACK3;
- // eliminate MOASI_SwapAvoidFallBack
- // PCG 04/08/98 split READ ME into separate file
- // PCG 04/22/98 merged Yan's changes to demo app
- // PCG 04/22/98 MOAS_ => MOASI_
- // PCG 04/22/98 threw out TempRoutineDescriptor
- // PCG 04/22/98 restructured MOASI_GetFile parameters to
- // better support MOASI_CustomGetFile
- // PCG 04/22/98 MOASI_CustomGetFile displays custom items
- // PCG 04/22/98 MOASI_CustomGetFileCore (to support
- // filtering of directories)
- // PCG 05/04/98 MOASI_StandardGetFilePreview (for QuickTime)
- // PCG 05/04/98 MOASI_CustomGetFilePreview (for QuickTime)
-
- #pragma mark INCLUDES
-
- #define OLDROUTINELOCATIONS 0
- #define OLDROUTINENAMES 0
- #define SystemSevenFiveOrLater 1
-
- #include "Navigation.h"
- #include "MoreOpenAndSave.h"
- #include "MoreProcesses.h"
-
- #include <LowMem.h>
- #include <Script.h>
- #include <Processes.h>
- #include <Resources.h>
- #include <MacMemory.h>
- #include <Sound.h>
- #include <PLStringFuncs.h>
-
- #pragma mark CONSTANTS
-
- enum
- {
- kUseOpenResourceTypes = -2,
- kAllFileTypes = -1,
- kOpenResType = 'open',
- kStandardOpenResID = 128
- };
-
- #pragma mark MACROS
-
- #define Assert(x) \
- do { if (!(x)) \
- ::DebugStr ("\p-=-=-=-=-=-\rassertion failed in file \"" __FILE__ \
- "\":\r " #x "\r-=-=-=-=-=-"); } while (0)
-
- #pragma mark TYPES
-
- typedef struct
- {
- bool filterDirs; // true only for CustomGetFile
- FileFilterYDUPP ffYDUPP; // non-NIL for CustomGetFile
- void *userData; // whatever the caller passed in
- short ditlResID; // non-zero if need items added
- ModalFilterYDUPP modalFilter; // may be non-nil for CustomGetFile and CustomPutFile
- DlgHookYDProcPtr dialogHook; // may be non-nil for CustomGetFile and CustomPutFile
- }
- tBridgeData, *tBridgeDataP, **tBridgeDataH;
-
- class NavLoader
- {
- bool fNeedUnload;
-
- public :
-
- NavLoader (OSErr &err)
- {
- err = ::NavLoad ( );
- fNeedUnload = err ? false : true;
- }
-
- ~NavLoader (void)
- {
- if (fNeedUnload)
- {
- OSErr err = ::NavUnload ( );
- Assert (err == noErr);
- }
- }
- };
-
- template <class T> class TempBuffer
- {
- //
- // This is a utility class for holding an arbitrary pointer temporarily.
- // This class is useful simply because class destructors are guaranteed
- // to run when instances of the class fall out of scope. This means we
- // don't have to have nested code to help us decide whether to call
- // DisposePtr.
- //
-
- T *fPtr;
-
- public :
-
- explicit TempBuffer (Ptr t, OSErr &err)
- {
- if (!t)
- {
- err = ::MemError ( );
- Assert (err != noErr);
- fPtr = nil;
- }
-
- Assert (::PtrZone (t) != nil);
- Assert (::MemError ( ) == noErr);
-
- fPtr = (T*) t;
- }
-
- ~TempBuffer (void)
- {
- if (fPtr)
- {
- ::DisposePtr (Ptr (fPtr));
- Assert (::MemError ( ) == noErr);
- }
- }
-
- T * operator -> (void) const
- {
- return fPtr;
- }
-
- operator T * (void) const
- {
- return fPtr;
- }
-
- T & operator * (void) const
- {
- return *fPtr;
- }
- };
-
- #pragma mark -
-
- static pascal OSErr MOASI_FSpGetCatInfo (const FSSpec &fss, CInfoPBPtr &cipbp)
- {
- //
- // Create a parameter block for PBGetCatInfo.
- // Fill it with data based on 'fss', appending
- // bytes for the filename at the end of the block.
- // Ask PBGetCatInfo to complete the block.
- // Produce a pointer to the augmented block.
- // Caller is expected to dispose the block.
- //
-
- OSErr err = noErr;
-
- cipbp = CInfoPBPtr (NewPtrClear (sizeof (*cipbp) + sizeof (Str31)));
-
- if (!cipbp)
- err = MemError ( );
- else
- {
- StringPtr entityName = StringPtr (cipbp) + sizeof (*cipbp);
-
- PLstrcpy (entityName,fss.name);
-
- cipbp->dirInfo.ioNamePtr = entityName;
- cipbp->dirInfo.ioVRefNum = fss.vRefNum;
- cipbp->dirInfo.ioDrDirID = fss.parID;
-
- err = PBGetCatInfoSync (cipbp);
-
- if (err)
- {
- DisposePtr (Ptr (cipbp));
- Assert (MemError ( ) == noErr);
- }
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_AEGetCatInfo (const AEDesc &fssDesc, CInfoPBPtr &cipbp)
- {
- //
- // Given an AEDesc of typeFSS, produce a filled-out
- // parameter block from PBGetCatInfo. Caller is
- // expected to dispose the block.
- //
-
- Assert (fssDesc.descriptorType == typeFSS);
-
- cipbp = nil;
-
- SInt8 hState = HGetState (fssDesc.dataHandle);
- Assert (MemError ( ) == noErr);
- MoveHHi (fssDesc.dataHandle);
- Assert (MemError ( ) == noErr);
- HLock (fssDesc.dataHandle);
- Assert (MemError ( ) == noErr);
-
- FSSpecPtr fssP = FSSpecPtr (*(fssDesc.dataHandle));
-
- OSErr err = MOASI_FSpGetCatInfo (*fssP,cipbp);
-
- HSetState (fssDesc.dataHandle, hState);
- Assert (MemError ( ) == noErr);
-
- return err;
- }
-
- static pascal OSErr MOASI_AECoerceAndGetCatInfo (const AEDesc &aeDesc, CInfoPBPtr &cipbp)
- {
- //
- // Given an AEDesc which can be coerced to typeFSS,
- // produce a filled-out parameter block from PBGetCatInfo.
- // Caller is expected to dispose the block.
- //
-
- cipbp = nil;
-
- OSErr err = noErr;
-
- AEDesc fssDesc;
-
- if (!(err = AECoerceDesc (&aeDesc, typeFSS, &fssDesc)))
- {
- err = MOASI_AEGetCatInfo (fssDesc,cipbp);
- OSErr err2 = AEDisposeDesc (&fssDesc);
- Assert (err2 == noErr);
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_AddDialogItems (short ditlResID, NavContext context)
- {
- OSErr err = noErr;
-
- Handle ditl = GetResource ('DITL',ditlResID);
-
- if (!ditl)
- {
- err = ResError ( );
- if (!err) err = resNotFound;
- }
- else
- {
- err = NavCustomControl (context, kNavCtlAddControlList, ditl);
- ReleaseResource (ditl);
- Assert (ResError ( ) == noErr);
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_NegotiateCustomRectSize (Rect &customRect)
- {
- OSErr err = noErr;
-
- //
- // We assume the documented minimum size will be accepted,
- // but we are ready to accept something larger if Nav offers.
- //
-
- enum
- {
- kMinimumDocumentedWidth = 400,
- kMinimumDocumentedHeight = 40
- };
-
- if (customRect.bottom)
- Assert (kMinimumDocumentedHeight <= customRect.bottom - customRect.top);
- else
- customRect.bottom = customRect.top + kMinimumDocumentedHeight;
-
- if (customRect.right)
- Assert (kMinimumDocumentedWidth <= customRect.right - customRect.left);
- else
- customRect.right = customRect.left + kMinimumDocumentedWidth;
-
- return err;
- }
-
- static pascal OSErr MOASI_HandleEvent
- (const tBridgeData &bridgeData, DialogPtr navDialog, const EventRecord &event, NavContext context)
- {
- OSErr err = noErr;
-
- if (event.what == mouseDown)
- {
- WindowPtr whichWindow;
- short fwPartCode = FindWindow (event.where,&whichWindow);
-
- if (fwPartCode == inContent && navDialog == whichWindow)
- {
- Point localWhere = event.where;
- GrafPtr preservedPort;
-
- GetPort (&preservedPort);
- SetPort (navDialog);
- // here's what we would do in a perfect world
- // GlobalToLocal (&localWhere);
- // but instead, we must hack to coddle Nav 1.0
- GetMouse (&localWhere);
- SetPort (preservedPort);
-
- DialogItemIndexZeroBased foundItem = FindDialogItem (navDialog,localWhere);
-
- if (foundItem >= 0)
- {
- DialogItemIndexZeroBased firstCustomItemIndex;
- if (!(err = NavCustomControl (context,kNavCtlGetFirstControlID,&firstCustomItemIndex)))
- {
- if (foundItem >= firstCustomItemIndex)
- {
- EventRecord abuseEvent = event;
- DialogItemIndex abuseIndex = foundItem + 1;
-
- (void) CallModalFilterYDProc (bridgeData.modalFilter, navDialog, &abuseEvent, &abuseIndex, bridgeData.userData);
- }
- }
- }
- }
- }
-
- return err;
- }
-
- static pascal void MOASI_EventFilterBridge
- (NavEventCallbackMessage message, NavCBRecPtr param, NavCallBackUserData myData)
- {
- OSErr err = noErr;
-
- tBridgeDataP bridgeData = tBridgeDataP (myData);
-
- switch (message)
- {
- case kNavCBEvent :
-
- if (bridgeData->modalFilter)
- err = MOASI_HandleEvent (*bridgeData,param->window,*(param->eventData.eventDataParms.event),param->context);
- break;
-
- case kNavCBCustomize :
-
- if (bridgeData->ditlResID)
- err = MOASI_NegotiateCustomRectSize (param->customRect);
- break;
-
- case kNavCBStart :
-
- if (bridgeData->ditlResID)
- err = MOASI_AddDialogItems (bridgeData->ditlResID, param->context);
- break;
- }
-
- if (err) SysBeep (-1);
- }
-
- static pascal Boolean MOASI_FileSystemFilterBridgeFromYD (CInfoPBPtr pb, void *yourDataPtr)
- {
- return CallFileFilterProc (FileFilterUPP (yourDataPtr), pb);
- }
-
- static pascal Boolean MOASI_FileSystemFilterBridgeToSFYD
- (AEDesc *item, void *, NavCallBackUserData callBackUD, NavFilterModes)
- {
- //
- // Given Nav file filter function parameters, translate to Standard
- // File terms and call a PACK 3 -style file filter function.
- // This function is called only from within Nav.
- //
-
- Assert (callBackUD);
- tBridgeDataP userDataP = tBridgeDataP (callBackUD);
- Assert (nil != userDataP->ffYDUPP);
-
- OSErr err = noErr;
- Boolean keepIt = true;
- CInfoPBPtr cipbp = nil;
-
- if (!(err = MOASI_AECoerceAndGetCatInfo (*item,cipbp)))
- {
- Assert (cipbp != nil);
-
- if (cipbp->hFileInfo.ioFlAttrib & ioDirMask)
- {
- if (userDataP->filterDirs)
- keepIt = !CallFileFilterYDProc (userDataP->ffYDUPP, cipbp, userDataP->userData);
- }
- else
- {
- const OSType kFileTypeDoesNotExist = 'ƒldr';
-
- if (cipbp->hFileInfo.ioFlFndrInfo.fdType == kFileTypeDoesNotExist)
- keepIt = false;
- else
- keepIt = !CallFileFilterYDProc (userDataP->ffYDUPP, cipbp, userDataP->userData);
- }
-
- DisposePtr (Ptr (cipbp));
- Assert (MemError ( ) == noErr);
- }
-
- return err ? false : keepIt;
- }
-
- static pascal OSErr MOASI_NewNavTypeList
- (short numTypes, ConstSFTypeListPtr typeList, NavTypeListHandle &result)
- {
- //
- // Given PACK 3 filtering data, create and fill a
- // NavTypeListHandle. Caller is expected to dispose it.
- //
-
- OSErr err = noErr;
-
- result = nil;
-
- //
- // If caller wants the old StandardOpenDialog behavior,
- // go get the standard open resource and copy it so it
- // can be disposed without any inconvenience.
- //
-
- if (numTypes == kUseOpenResourceTypes)
- {
- UInt8 preservedResLoad = LMGetResLoad ( );
-
- SetResLoad (false);
-
- Handle openResource = GetResource (kOpenResType,kStandardOpenResID);
- err = ResError ( );
-
- SetResLoad (preservedResLoad ? true : false);
-
- if (!openResource)
- {
- if (!err) err = resNotFound;
- }
- else
- {
- err = noErr;
-
- Boolean resourceWasLoaded = *result ? true : false;
-
- if (!resourceWasLoaded)
- {
- LoadResource (openResource);
- err = ResError ( );
- }
-
- if (!err)
- {
- SInt8 hState = HGetState (openResource);
- Assert (!MemError ( ));
- HNoPurge (openResource);
- Assert (!MemError ( ));
-
- Handle openResourceCopy = openResource;
-
- if (!(err = HandToHand (&openResourceCopy)))
- result = NavTypeListHandle (openResourceCopy);
-
- HSetState (openResource,hState);
- Assert (!MemError ( ));
-
- if (!resourceWasLoaded)
- {
- EmptyHandle (Handle (result));
- Assert (!MemError ( ));
- }
- }
-
- ReleaseResource (openResource);
- Assert (!ResError ( ));
- }
- }
-
- //
- // If the caller specified some file types, build the corresponding
- // Nav data structure, which just happens to be in the same format as
- // the old 'kind' resource. (What a coincidence!)
- //
-
- else if (numTypes > 0)
- {
- result = NavTypeListHandle (NewHandle (sizeof (NavTypeList) + (numTypes * sizeof (OSType))));
-
- if (!result)
- err = MemError ( );
- else
- {
- TempBuffer <ProcessInfoRec> pirP (NewPtr (sizeof (ProcessInfoRec)), err);
-
- if (!err && !(err = GetSomeProcessInfo (nil,pirP)))
- {
- (**result).componentSignature = pirP->processSignature;
- (**result).osTypeCount = numTypes;
-
- BlockMoveData (typeList, (**result).osType, numTypes * sizeof (OSType));
- }
-
- if (err)
- {
- DisposeHandle (Handle (result));
- result = nil;
- }
- }
- }
-
- return err;
- }
-
- static pascal void MOASI_ClearStandardFileReply (StandardFileReply &sfReply)
- {
- //
- // One would hope it's obvious what this function does
- // from reading it. WHY and WHEN you'd want to do this
- // is another matter. Read the comments in the callers.
- //
-
- sfReply.sfGood = false;
- sfReply.sfReplacing = false;
- sfReply.sfType = 0;
- sfReply.sfFile.parID = 0;
- sfReply.sfFile.vRefNum = 0;
- sfReply.sfFile.name [0] = 0;
- sfReply.sfScript = 0;
- sfReply.sfFlags = 0;
- sfReply.sfIsFolder = false;
- sfReply.sfIsVolume = false;
- sfReply.sfReserved1 = 0;
- sfReply.sfReserved2 = 0;
- }
-
- static pascal OSErr MOASI_TranslateNavReply
- (const NavReplyRecord &navReply, StandardFileReply &sfReply, bool simulatingGet)
- {
- //
- // Given a Nav reply record, translate it to a PACK 3 reply record.
- // We assume the PACK 3 reply record has been completely cleared
- // (probably by MOASI_ClearStandardFileReply).
- //
-
- OSErr err = noErr;
-
- AEDesc firstDesc;
- AEKeyword ignoreKeyword;
-
- if (!(err = AEGetNthDesc (&(navReply.selection), 1, typeFSS, &ignoreKeyword, &firstDesc)))
- {
- MoveHHi (firstDesc.dataHandle);
- Assert (MemError ( ) == noErr);
- HLock (firstDesc.dataHandle);
- Assert (MemError ( ) == noErr);
-
- FSSpecPtr fssP = FSSpecPtr (*(firstDesc.dataHandle));
-
- //
- // This is the same logic PACK 3 uses;
- // we emulate it here even though we don't expect
- // to ever be called with navReply.validRecord false.
- // In fact, we assert that we are not. Yes, I do
- // know how many A's are in "anal".
- //
-
- sfReply.sfFile.vRefNum = fssP->vRefNum;
- sfReply.sfFile.parID = fssP->parID;
-
- sfReply.sfGood = navReply.validRecord;
-
- Assert (sfReply.sfGood == true);
-
- if (sfReply.sfGood)
- {
- PLstrcpy (sfReply.sfFile.name, fssP->name);
-
- if (simulatingGet)
- {
- //
- // PACK 3 does not have to get the catalog info;
- // it caches what it needs. We don't have that luxury.
- //
-
- CInfoPBPtr cipbp;
-
- if (!(err = MOASI_FSpGetCatInfo (*fssP,cipbp)))
- {
- sfReply.sfScript = cipbp->hFileInfo.ioFlXFndrInfo.fdScript;
- sfReply.sfFlags = cipbp->hFileInfo.ioFlFndrInfo.fdFlags;
-
- if (!(cipbp->hFileInfo.ioFlAttrib & ioDirMask))
- sfReply.sfType = cipbp->hFileInfo.ioFlFndrInfo.fdType;
- else if (fssP->parID == fsRtParID)
- sfReply.sfIsVolume = true;
- else
- sfReply.sfIsFolder = true;
-
- DisposePtr (Ptr (cipbp));
- Assert (noErr == MemError ( ));
- }
- }
- else
- {
- //
- // Yan's code has a comment that wonders whether we
- // should be getting the script from Nav. It's unlikely
- // to have changed between then and now, but it would be
- // cleaner.
- //
- // Since I'm no Script Manager expert, I should look up
- // whether it's safe to call GetScriptManagerVariable on
- // all systems under which Nav is supported.
- //
-
- sfReply.sfScript = GetScriptManagerVariable (smKeyScript);
-
- //
- // PACK 3 sets sfReplacing on the fly, just after
- // the user confirms whether it's OK. We don't confirm
- // anything ourselves, so we must set it here.
- //
-
- sfReply.sfReplacing = navReply.replacing;
- }
- }
-
- OSErr err2 = AEDisposeDesc (&firstDesc);
- Assert (err2 == noErr);
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_GetFile
- (short numTypes, ConstSFTypeListPtr typeList, StandardFileReply *reply, const tBridgeData *bridgeData,
- NavEventUPP eventUPP, NavObjectFilterUPP objectFilterUPP)
- {
- //
- // Given PACK 3 parameters, translate them to Nav terms and
- // call Nav to simulate StandardGetFile.
- //
-
- OSErr err = noErr;
-
- //
- // We explicitly load and unload Nav because callers of Standard
- // File may expect it to be completely removed from memory when
- // it is done, and Nav has a deferred unloading scheme.
- //
-
- NavLoader navLoader (err);
- if (err) return err;
-
- //
- // Allocate some buffers we'll need; they'll be automagically disposed.
- //
-
- TempBuffer <NavReplyRecord> navReply (NewPtr (sizeof (NavReplyRecord)), err);
- if (err) return err;
- TempBuffer <NavDialogOptions> navOptions (NewPtr (sizeof (NavDialogOptions)), err);
- if (err) return err;
-
- //
- // Ask Nav to fill in its default dialog options.
- // We will over-ride some of them later.
- //
-
- err = NavGetDefaultDialogOptions (navOptions);
- if (err) return err;
-
- NavTypeListHandle navTypeList = nil;
-
- err = MOASI_NewNavTypeList (objectFilterUPP ? (numTypes == kUseOpenResourceTypes ? -1 : numTypes) : numTypes, typeList, navTypeList);
-
- if (!err || err == resNotFound) // it's OK if we could not find the 'open' resource
- {
- navOptions->preferenceKey = (**navTypeList).componentSignature;
- navOptions->dialogOptionFlags = kNavAllowPreviews;
-
- if (numTypes == -1 || numTypes == 0)
- {
- navOptions->dialogOptionFlags |= kNavNoTypePopup;
- navOptions->dialogOptionFlags |= kNavDontAutoTranslate;
- }
-
- if (objectFilterUPP)
- navOptions->dialogOptionFlags |= kNavAllowInvisibleFiles;
-
- NavCallBackUserData navCallBackUserData = NavCallBackUserData (bridgeData);
-
- err = NavGetFile (nil, navReply, navOptions, eventUPP, nil, objectFilterUPP, navTypeList, navCallBackUserData);
-
- if (err == userCanceledErr)
- err = noErr;
- else if (!err)
- {
- if (navReply->validRecord)
- {
- err = MOASI_TranslateNavReply (*navReply,*reply,true);
- }
-
- OSErr err2 = NavDisposeReply (navReply);
- Assert (err2 == noErr);
- }
-
- DisposeHandle (Handle (navTypeList));
- Assert (noErr == MemError ( ));
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_PutFile
- (ConstStr255Param prompt, ConstStr255Param defaultName, StandardFileReply *reply)
- {
- //
- // Given PACK 3 parameters, translate them to Nav terms and
- // call Nav to simulate StandardGetFile.
- //
-
- OSErr err = noErr;
-
- //
- // We explicitly load and unload Nav because callers of Standard
- // File may expect it to be completely removed from memory when
- // it is done, and Nav has a deferred unloading scheme.
- //
-
- NavLoader navLoader (err);
- if (err) return err;
-
- //
- // Allocate some buffers we'll need; they'll be automagically disposed.
- //
-
- TempBuffer <NavReplyRecord> navReply (NewPtr (sizeof (NavReplyRecord)), err);
- if (err) return err;
- TempBuffer <NavDialogOptions> navOptions (NewPtr (sizeof (NavDialogOptions)), err);
- if (err) return err;
- TempBuffer <ProcessInfoRec> pirP (NewPtr (sizeof (ProcessInfoRec)), err);
- if (err) return err;
-
- //
- // Get some information about the current process, including its creator code.
- //
-
- err = GetSomeProcessInfo (nil,pirP);
- if (err) return err;
-
- //
- // Ask Nav to fill in its default dialog options.
- // Over-ride the ones we don't like.
- //
-
- err = NavGetDefaultDialogOptions (navOptions);
- if (err) return err;
-
- navOptions->preferenceKey = pirP->processSignature;
- navOptions->dialogOptionFlags = kNavNoTypePopup | kNavDontAddTranslateItems;
-
- PLstrcpy (navOptions->savedFileName,defaultName);
- PLstrcpy (navOptions->message,prompt);
-
- err = NavPutFile (nil,navReply,navOptions,nil,0,0,nil);
-
- if (err == userCanceledErr)
- err = noErr;
- else if (!err)
- {
- if (navReply->validRecord)
- {
- err = MOASI_TranslateNavReply (*navReply,*reply,false);
- }
-
- OSErr err2 = NavDisposeReply (navReply);
- Assert (err2 == noErr);
- }
-
- return err;
- }
-
- static pascal OSErr MOASI_CustomGetFileCore ( volatile FileFilterYDUPP fileFilter,
- volatile short numTypes,
- volatile ConstSFTypeListPtr typeList,
- StandardFileReply * volatile reply,
- volatile short ditlResID,
- volatile DlgHookYDProcPtr dialogHook,
- volatile ModalFilterYDUPP modalFilter,
- void * volatile yourDataPtr,
- volatile Boolean filterDirs )
- {
- OSErr err = noErr;
-
- //
- // PACK 3 ALWAYS clears the record.
- // PACK 3 also fills in some fields even
- // when sfGood is false. I'm not sure how to
- // translate this, so I'm just going to punt it.
- // Nav's model is just too different.
- //
-
- MOASI_ClearStandardFileReply (*reply);
-
- //
- // In order to add items to the dialog, we must specify a non-nil event filter
- // to Nav. If we specify a non-nil event filter, Nav will assume it's OK to
- // be movable-modal. If Nav is movable-modal, we need someone to handle events.
- // Ergo, it's not possible to add items to a dialog without handling events.
- //
-
- Assert (!ditlResID || modalFilter);
-
- //
- // Before we bother to do anything more expensive than parameter validation,
- // we make sure Nav is around, so we don't waste time allocating memory which
- // will never be used.
- //
-
- if (NavServicesAvailable ( ))
- {
- NavEventUPP eventUPP = nil;
-
- if (modalFilter || ditlResID || dialogHook)
- {
- eventUPP = NewNavEventProc (MOASI_EventFilterBridge);
- if (!eventUPP) err = MemError ( );
- }
-
- if (!err)
- {
- NavObjectFilterUPP objectFilterUPP = nil;
-
- if (fileFilter)
- {
- objectFilterUPP = NewNavObjectFilterProc (MOASI_FileSystemFilterBridgeToSFYD);
- if (!objectFilterUPP) err = MemError ( );
- }
-
- if (!err)
- {
- tBridgeData bridgeData =
- {
- filterDirs,
- fileFilter,
- yourDataPtr,
- ditlResID,
- modalFilter,
- dialogHook
- };
-
- err = MOASI_GetFile (numTypes,typeList,reply,&bridgeData,eventUPP,objectFilterUPP);
- if (objectFilterUPP) DisposeRoutineDescriptor (objectFilterUPP);
- }
-
- if (eventUPP) DisposeRoutineDescriptor (eventUPP);
- }
- }
-
- return err;
- }
-
- #pragma mark -
-
- pascal OSErr MOASI_CustomGetFile ( volatile FileFilterYDUPP fileFilter,
- volatile short numTypes,
- volatile ConstSFTypeListPtr typeList,
- StandardFileReply * volatile reply,
- volatile short ditlResID,
- volatile DlgHookYDProcPtr dialogHook,
- volatile ModalFilterYDUPP modalFilter,
- void * volatile yourDataPtr )
- {
- //
- // Just pass params thru to CustomGetFileCore
- // and specify that we do want to filter directories.
- //
-
- return MOASI_CustomGetFileCore (fileFilter,numTypes,typeList,reply,ditlResID,dialogHook,modalFilter,yourDataPtr,true);
- }
-
- pascal OSErr MOASI_CustomPutFile ( volatile ConstStr255Param prompt,
- volatile ConstStr255Param defaultName,
- StandardFileReply * volatile reply,
- volatile short ditlResID,
- volatile DlgHookYDProcPtr,
- volatile ModalFilterYDUPP,
- void * volatile yourDataPtr )
- {
- #pragma unused(ditlResID)
- #pragma unused(yourDataPtr)
- OSErr err = noErr;
-
- //
- // PACK 3 ALWAYS clears the record.
- // PACK 3 also fills in some fields even
- // when sfGood is false. I'm not sure how to
- // translate this, so I'm just going to punt it.
- // Nav's model is just too different.
- //
-
- MOASI_ClearStandardFileReply (*reply);
-
- if (NavServicesAvailable ( ))
- err = MOASI_PutFile (prompt,defaultName,reply);
-
- return err;
- }
-
- pascal OSErr MOASI_StandardGetFile ( volatile FileFilterUPP fileFilter,
- volatile short numTypes,
- volatile ConstSFTypeListPtr typeList,
- StandardFileReply * volatile reply )
- {
- //
- // Call CustomGetFileCore with mostly "no-op" parameters,
- // transforming the simple file filter into a YD filter,
- // and specifying that we do not want to filter directories.
- //
-
- OSErr err = noErr;
-
- FileFilterYDUPP ydupp = nil;
-
- if (fileFilter)
- {
- ydupp = NewFileFilterYDProc (MOASI_FileSystemFilterBridgeFromYD);
-
- if (!ydupp)
- {
- MOASI_ClearStandardFileReply (*reply);
- err = MemError ( );
- }
- }
-
- if (!err)
- {
- err = MOASI_CustomGetFileCore (ydupp,numTypes,typeList,reply,0,nil,nil,fileFilter,false);
- if (ydupp) DisposeRoutineDescriptor (ydupp);
- }
-
- return err;
- }
-
- pascal OSErr MOASI_StandardPutFile ( volatile ConstStr255Param prompt,
- volatile ConstStr255Param defaultName,
- StandardFileReply * volatile reply )
- {
- //
- // Just call CustomPut with some "no-op" parameters.
- //
-
- return MOASI_CustomPutFile (prompt,defaultName,reply,0,nil,nil,nil);
- }
-
- pascal OSErr MOASI_StandardOpenDialog (StandardFileReply * volatile reply)
- {
- //
- // Just call StandardGet with some sentinel values (see Translation Manager chapter).
- //
-
- return MOASI_StandardGetFile (nil,kUseOpenResourceTypes,nil,reply);
- }
-
- pascal OSErr MOASI_StandardGetFilePreview ( volatile FileFilterUPP fileFilter,
- volatile short numTypes,
- volatile ConstSFTypeListPtr typeList,
- StandardFileReply * volatile reply )
- {
- //
- // Nav assimilates the QuickTime file browsing feature set,
- // so just call through.
- //
-
- return MOASI_StandardGetFile (fileFilter,numTypes,typeList,reply);
- }
-
- pascal OSErr MOASI_CustomGetFilePreview ( volatile FileFilterYDUPP fileFilter,
- volatile short numTypes,
- volatile ConstSFTypeListPtr typeList,
- StandardFileReply * volatile reply,
- volatile short ditlResID,
- volatile DlgHookYDProcPtr dialogHook,
- volatile ModalFilterYDUPP modalFilter,
- void * volatile yourDataPtr )
- {
- //
- // Nav assimilates the QuickTime file browsing feature set,
- // so just call through.
- //
-
- return MOASI_CustomGetFile (fileFilter,numTypes,typeList,reply,ditlResID,dialogHook,modalFilter,yourDataPtr);
- }
-